#!/usr/bin/env python3
import os
import docker
import logging
import subprocess
import stat

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def run_command(cmd):
    """运行shell命令"""
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
        return result.returncode == 0, result.stdout, result.stderr
    except Exception as e:
        return False, "", str(e)

def check_docker_connection():
    """检查Docker连接状态"""
    print("=" * 50)
    print("Docker连接诊断工具")
    print("=" * 50)
    
    # 1. 检查Docker服务状态
    print("\n1. 检查Docker服务状态:")
    success, stdout, stderr = run_command("sudo systemctl status docker")
    if success:
        if "active (running)" in stdout:
            print("✓ Docker服务正在运行")
        else:
            print("✗ Docker服务未运行")
            print("尝试启动Docker服务...")
            start_success, _, _ = run_command("sudo systemctl start docker")
            if start_success:
                print("✓ Docker服务启动成功")
            else:
                print("✗ Docker服务启动失败")
                return None
    else:
        print("✗ 无法检查Docker服务状态")
    
    # 2. 检查Docker socket文件
    print("\n2. 检查Docker socket文件:")
    socket_paths = [
        '/var/run/docker.sock',
        '/run/docker.sock'
    ]
    
    socket_found = False
    for path in socket_paths:
        if os.path.exists(path):
            print(f"✓ 找到socket文件: {path}")
            socket_found = True
            
            # 检查文件类型
            if not os.path.isdir(path):
                print(f"  ✓ 是文件类型")
            else:
                print(f"  ✗ 是目录，不是socket文件")
                continue
            
            # 检查文件权限
            try:
                mode = os.stat(path).st_mode
                if stat.S_ISSOCK(mode):
                    print(f"  ✓ 是有效的socket文件")
                else:
                    print(f"  ✗ 不是socket文件类型")
                    continue
                    
                # 检查权限
                if os.access(path, os.R_OK | os.W_OK):
                    print(f"  ✓ 有读写权限")
                else:
                    print(f"  ✗ 权限不足，当前权限: {oct(mode)[-3:]}")
                    print(f"  尝试修复权限...")
                    try:
                        os.chmod(path, 0o666)
                        print(f"  ✓ 权限已修复为666")
                    except Exception as e:
                        print(f"  ✗ 权限修复失败: {e}")
                        
            except Exception as e:
                print(f"  ✗ 检查文件失败: {e}")
                continue
                
            break
    
    if not socket_found:
        print("✗ 未找到Docker socket文件")
        print("请确保Docker服务已安装并启动")
        return None
    
    # 3. 检查当前用户权限
    print("\n3. 检查用户权限:")
    current_user = os.getenv('USER')
    print(f"当前用户: {current_user}")
    
    # 检查用户是否在docker组
    in_docker_group = False
    try:
        groups_output = subprocess.check_output(["groups", current_user], text=True)
        if "docker" in groups_output:
            print("✓ 用户在docker组中")
            in_docker_group = True
        else:
            print("✗ 用户不在docker组中")
    except:
        print("✗ 无法检查用户组信息")
    
    # 4. 尝试不同的连接方式
    print("\n4. 尝试连接Docker:")
    connection_methods = [
        ('unix:///var/run/docker.sock', 'Unix socket (/var/run/docker.sock)'),
        ('unix:///run/docker.sock', 'Unix socket (/run/docker.sock)'),
        ('tcp://127.0.0.1:2375', 'TCP (127.0.0.1:2375)'),
        ('tcp://localhost:2375', 'TCP (localhost:2375)'),
    ]
    
    successful_connection = None
    
    for url, description in connection_methods:
        try:
            print(f"尝试: {description}")
            # 临时设置环境变量
            original_docker_host = os.environ.get('DOCKER_HOST')
            os.environ['DOCKER_HOST'] = url
            
            client = docker.from_env(timeout=5)
            version_info = client.version()
            print(f"✓ 成功! Docker版本: {version_info['Version']}")
            successful_connection = url
            break
        except docker.errors.DockerException as e:
            print(f"✗ Docker连接失败: {e}")
        except Exception as e:
            print(f"✗ 其他错误: {e}")
        finally:
            # 恢复原始环境变量
            if original_docker_host is not None:
                os.environ['DOCKER_HOST'] = original_docker_host
            elif 'DOCKER_HOST' in os.environ:
                del os.environ['DOCKER_HOST']
    
    if successful_connection:
        print(f"\n✓ 诊断完成: 建议使用 {successful_connection}")
        return successful_connection
    else:
        print("\n✗ 所有连接方式都失败了!")
        
        # 提供修复建议
        print("\n修复建议:")
        if not in_docker_group:
            print("1. 将当前用户添加到docker组:")
            print(f"   sudo usermod -aG docker {current_user}")
            print("   然后需要重新登录或重启生效")
        
        print("2. 或者临时使用sudo权限:")
        print("   sudo chmod 666 /var/run/docker.sock")
        
        print("3. 检查Docker服务配置:")
        print("   sudo systemctl status docker")
        print("   journalctl -u docker.service")
        
        return None

def quick_fix():
    """快速修复Docker权限问题"""
    print("\n" + "="*50)
    print("快速修复Docker权限")
    print("="*50)
    
    # 尝试修复socket权限
    socket_path = '/var/run/docker.sock'
    if os.path.exists(socket_path):
        try:
            # 临时修复权限
            run_command(f"sudo chmod 666 {socket_path}")
            print("✓ 已尝试修复socket权限")
        except:
            print("✗ 权限修复失败")
    
    # 检查用户是否在docker组
    current_user = os.getenv('USER')
    success, stdout, stderr = run_command(f"groups {current_user}")
    if success and "docker" not in stdout:
        print("建议将用户添加到docker组:")
        print(f"sudo usermod -aG docker {current_user}")
        print("然后需要重新登录或重启")

if __name__ == '__main__':
    result = check_docker_connection()
    
    if not result:
        quick_fix()
        
    if result:
        print(f"\n请在环境变量中设置:")
        print(f"export DOCKER_HOST={result}")
        print("\n或者运行应用时使用:")
        print(f"DOCKER_HOST={result} python app.py")
    else:
        print("\n无法连接到Docker，请检查Docker服务状态")
